package com.lagou.client;

import com.lagou.handler.UserClientHandler;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;

public class RPCConsumer {

  // 线程池
  public static ExecutorService executorService =
      Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());

  public static UserClientHandler client;

  public Object creatProxy(Class<?> serverClass, String param) {
    return Proxy.newProxyInstance(
        Thread.currentThread().getContextClassLoader(),
        new Class[] {serverClass},
        new InvocationHandler() {
          public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            if (client == null) {
              initClient();
            }
            // 设置参数
            client.serParam(param + args[0]);
            return executorService.submit(client).get();
          }
        });
  }

  private void initClient() {
    try {
      client = new UserClientHandler();
      NioEventLoopGroup loopGroup = new NioEventLoopGroup();
      Bootstrap bootstrap = new Bootstrap();
      bootstrap
          .group(loopGroup)
          .channel(NioSocketChannel.class)
          .option(ChannelOption.TCP_NODELAY, true)
          .handler(
              new ChannelInitializer<SocketChannel>() {
                @Override
                protected void initChannel(SocketChannel socketChannel) throws Exception {
                  ChannelPipeline pipeline = socketChannel.pipeline();
                  pipeline.addLast(new StringDecoder());
                  pipeline.addLast(new StringEncoder());
                  pipeline.addLast(client);
                }
              });
      bootstrap.connect("127.0.0.1", 8999).sync();
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
  }
}
